package ar.com.santiagobasulto.crawler.core;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.net.URLConnection;
import java.util.Set;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;

import javax.swing.text.html.HTMLEditorKit;

public class URLFinder implements Runnable{

    private BlockingQueue<URL> notCrawledURLs;
    private Set<URL> crawledURLs;

    private URLProcessorManager processorManager;

    public URLFinder(BlockingQueue<URL> notCrawledURLs, Set<URL> crawledURLs, URLProcessorManager processorManager){
        this.notCrawledURLs = notCrawledURLs;
        this.crawledURLs = crawledURLs;
        this.processorManager = processorManager;
    }

    @Override
    public void run(){
        try {
            boolean done = false;
            while(!done){
                URL url = notCrawledURLs.poll(TIME_TO_WAIT_WHILE_POLLING,TIME_UNIT);
                if(url==null){
                    //There's no more URLs, shoud i finish?
                    done=true;
                }else{
                	boolean proceed = false;
                	synchronized (crawledURLs) {
    					if(!crawledURLs.contains(url)){
    						proceed = true;
    						crawledURLs.add(url);
    						//notProcessedURLs.put(url);
    						processorManager.offer(url);
    					}
    				}
                	if(proceed){
    					//System.out.println("Procesando: "+url);
    					processURL(url);
                	}
                }
            }
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @SuppressWarnings("serial")
	private void processURL(URL url){
    	//System.out.println("Processing URL:" +url.toString());
    	WebCrawlerLogger.log.log(Level.INFO, "Procesando "+url);
    	URLConnection connection;
        try {
            connection = url.openConnection();
            //TODO check type of connection
            //TODO catch exception to check for
            InputStream in = connection.getInputStream();
            Reader r = new InputStreamReader(in);

            HTMLEditorKit.Parser parse = new HTMLEditorKit(){
                public HTMLEditorKit.Parser getParser(){
                	return super.getParser();
                }
            }.getParser();

            parse.parse(r,new Parser(url,this),true);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            //e.printStackTrace();
            WebCrawlerLogger.log.log(Level.WARNING, "Error procesando la URL: "+url);
        }
    }
    public synchronized void offer(URL url){
    	WebCrawlerLogger.log.log(Level.INFO, "New URL offered = "+url);
    	synchronized (crawledURLs) {
    		if(!crawledURLs.contains(url))
    			notCrawledURLs.add(url);
		}
    }
    /*public void run() {
    try {
        boolean done = false;
        while(!done){
            URL url = notCrawledURLs.take();
            if(url == WebCrawler.DUMMY){
                notCrawledURLs.put(url);
                done = true;
            }else{
                if(!crawledURLs.contains(url)){
                    //TODO create a URLConnection
                    //TODO parse the InputStream from URLConnection
                    //TODO find more URLs
                }
            }
        }
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}*/
    public static void setTimeToWait(long time,TimeUnit timeUnit){
    	URLFinder.TIME_TO_WAIT_WHILE_POLLING = time;
    	URLFinder.TIME_UNIT = timeUnit;
    }
    private static long TIME_TO_WAIT_WHILE_POLLING = 3;
    private static TimeUnit TIME_UNIT = TimeUnit.SECONDS;
}
